package com.feng.oauth2jwt.oauth.infrastructure.jdbc;



import com.feng.oauth2jwt.oauth.domain.user.Privilege;
import com.feng.oauth2jwt.oauth.domain.user.User;
import com.feng.oauth2jwt.oauth.domain.user.UserRepository;
import com.feng.oauth2jwt.oauth.infrastructure.DateUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;


@Repository("userRepositoryJdbc")
public class UserRepositoryJdbc implements UserRepository {


    private static UserRowMapper userRowMapper = new UserRowMapper();

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public User findByGuid(String guid) {
        final String sql = " select * from user_ where  guid = ? ";
        final List<User> list = this.jdbcTemplate.query(sql, new Object[]{guid}, userRowMapper);

        User user = null;
        if (!list.isEmpty()) {
            user = list.get(0);
            user.privileges().addAll(findPrivileges(user.id()));
        }

        return user;
    }

    private Collection<Privilege> findPrivileges(int userId) {
        final String sql = " select privilege from user_privilege where user_id = ? ";
        final List<String> strings = this.jdbcTemplate.queryForList(sql, new Object[]{userId}, String.class);

        List<Privilege> privileges = new ArrayList<Privilege>(strings.size());
        for (String str : strings) {
            privileges.add(Privilege.valueOf(str));
        }
        return privileges;
    }

    @Override
    public void saveUser(final User user) {
        final String sql = " insert into user_(guid,archived,create_time,email,password,username,phone,client_id) " +
                " values (?,?,?,?,?,?,?,?) ";
        this.jdbcTemplate.update(sql, user.guid(), user.archived(),  DateUtils.toDateTime(user.createTime()), user.email(), user.password(), user.username(), user.phone(),user.clientId());

//        //get user id
//        final Integer id = this.jdbcTemplate.queryForObject("select id from user_ where guid = ?", new Object[]{user.guid()}, Integer.class);
//
//        //insert privileges
//        for (final Privilege privilege : user.privileges()) {
//            this.jdbcTemplate.update("insert into user_privilege(user_id, privilege) values (?,?)",  id, privilege.name());
//        }

    }

    @Override
    public void updateUser(final User user) {
        final String sql = " update user_ set username = ?, password = ?, phone = ?,email = ? where guid = ? ";
        this.jdbcTemplate.update(sql, user.username(), user.password(), user.phone(), user.email(), user.guid());
    }
    
    @Override
//    @CacheEvict(value = USER_CACHE, key = "#user.username()")
    public void updateUserPassword(final User user) {
        final String sql = " update user_ set  password = ? where guid = ? ";
        this.jdbcTemplate.update(sql, user.password(), user.guid());
    }

    @Override
//    @Cacheable(value = USER_CACHE, key = "#username")
    public User findByUsername(String username) {
        final String sql = " select * from user_ where username = ? and archived = 0 ";
        final List<User> list = this.jdbcTemplate.query(sql, new Object[]{username}, userRowMapper);

        User user = null;
        if (!list.isEmpty()) {
            user = list.get(0);
            user.privileges().addAll(findPrivileges(user.id()));
        }

        return user;
    }

    @Override
    public List<User> findUsersByUsername(String username) {
        String sql = " select * from user_ where archived = 0 ";
        Object[] params = new Object[]{};
        if (StringUtils.isNotEmpty(username)) {
            sql += " and username = ?";
            params = new Object[]{username};
        }
        sql += " order by create_time desc ";

        final List<User> list = this.jdbcTemplate.query(sql, params, userRowMapper);
        for (User user : list) {
            user.privileges().addAll(findPrivileges(user.id()));
        }
        return list;
    }

    @Override
    public User findByClientId(String client_id) {
        final String sql = " select * from user_ where client_id = ? and archived = 0 ";
        final List<User> list = this.jdbcTemplate.query(sql, new Object[]{client_id}, userRowMapper);

        User user = null;
        if (!list.isEmpty()) {
            user = list.get(0);
            user.privileges().addAll(findPrivileges(user.id()));
        }

        return user;
    }

}
